//
//  WDDiscoverViewController.m
//  winterTest
//
//  Created by wd on 15/10/26.
//  Copyright © 2015年 Wei Chuang Le ,Ltd. All rights reserved.
//

#import "WDDiscoverViewController.h"

@interface WDDiscoverViewController ()

@end

@implementation WDDiscoverViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blueColor];
    
//    if (ShowVC_Type_Modal == self.showVC_Type) {
////        UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
////        [rightBtn setTitle:@"取消" forState:UIControlStateNormal];
////        [rightBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
////        [rightBtn addTarget:self action:@selector(cancleButtonClicked) forControlEvents:UIControlEventTouchUpInside];
////        UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:rightBtn];
////        self.navigationItem.rightBarButtonItems = @[rightItem];
//        UIBarButtonItem *barBtn1=[[UIBarButtonItem alloc]initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(cancleButtonClicked)];
//        self.navigationItem.leftBarButtonItem=barBtn1;
//    }
    
    [self testGroupMultitask];
//    [self testGCD_Group_FakeRequest];
//    [self testGCD_Serial];
//    [self testGroupQueue];
}

- (void)cancleButtonClicked
{
    if (self.cancleActionBlock) {
        self.cancleActionBlock(YES);
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)fakeRequestWithDelay:(int)delaySeconds result:(void (^)(NSString *string, NSError *error))result
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delaySeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (result) {
            NSError *err = [NSError errorWithDomain:@"error" code:2 userInfo:nil];
            NSString *string = [NSString stringWithFormat:@"delay %i seconds",delaySeconds];
            result(string, delaySeconds%2 == 0 ? nil : err);
        }
    });
}

- (void)testGroupQueue
{
    NSLog(@"testGroupQueue===============");
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:1];
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"queue 1... threadPriority = %f",threadPriority);
    });
    
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:2];
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"queue 2... threadPriority = %f",threadPriority);
    });
    
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:3];
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"queue 3... threadPriority = %f",threadPriority);
    });
    
    dispatch_group_notify(group, queue, ^{
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"group done threadPriority = %f",threadPriority);
    });
}

- (void)testGroupMultitask
{
    NSLog(@"testGroupMultitask===============");
    // 1.创建任务组
    dispatch_group_t group = dispatch_group_create();
    // 2.加入第一个任务
    dispatch_group_enter(group);
    
    NSMutableString *groupResult = [NSMutableString string];
    
    // 模拟一个6秒的请求
    [self fakeRequestWithDelay:6 result:^(NSString *string, NSError *error) {
        /*
         在这里我们设置的dispatch_group_wait时间是5秒，但是我们这个任务的回调时间是6秒。所以结果是5秒过后wait超时，程序继续往下执行，打印-> "wait时间已经到了"。
         然而这个任务还在线程里执行，一直到执行dispatch_group_leave这个任务才完成。
         */
        NSString *result = [NSString stringWithFormat:@"任务组1完成 %@",string];
        [groupResult appendString:result];
        [groupResult appendString:@"\n"];
        NSLog(@"------%@",string);
//        dispatch_group_leave(group);
    }];
    
    // 3.加入第二个任务
    dispatch_group_enter(group);
    
    /*
     这里我发现一个问题，我设置的dispatch_after的延时时间是3秒，也就是3秒后把block中的任务加入线程;
     所以结果应该是在dispatch_group_wait时间内就能完成的，打印顺序应该是在 "wait时间已经到了" 之前才对， 但是打印的顺序却是先打印："wait时间已经到了"，然后打印：任务组2完成;
     我猜测这个延时执行的代码，是异步的等待，并不是阻塞线程的，
     */
    dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
    dispatch_after(tt, dispatch_get_main_queue(), ^{
        NSString *result = @"任务组2完成 delay 3 seconds";
        [groupResult appendString:result];
        [groupResult appendString:@"\n"];
        NSLog(@"------%@",result);
        dispatch_group_leave(group);
    });
    
    // 4.加入第三个任务
    dispatch_group_enter(group);
    NSString *result = @"任务组3完成";
    [groupResult appendString:result];
    [groupResult appendString:@"\n"];
    NSLog(@"------%@",result);
    dispatch_group_leave(group);
    
    // 5.执行到这句代码后会等待5秒，等待关联的任务组group里的所有任务完成。如果在5秒内都完成了，返回0并继续执行；如果超时未完成，返回非0并继续执行。所以任务组里的任务无论是否全部完成，都会继续执行。
    int waitTime = 5;
    dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime*NSEC_PER_SEC)));
    NSLog(@"wait时间已经到了 %i seconds",waitTime);
    
    // 6.notify会简体关联的任务组group中的所有任务是否都已完成（dispatch_group_enter和dispatch_group_leave匹配），完成了就会执行block
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"------所有任务组都完成了 \n %@",groupResult);
    });
}

// test 异步并发 GCD
- (void)testGCD_Group_FakeRequest
{
    NSLog(@"testGCD_Group===============");
    // 1，创建异步队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 2，创建 一组 任务
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{
        
        [self fakeRequestWithDelay:3 result:^(NSString *string, NSError *error) {
            
            NSLog(@"group 1...result = %@", string);
        }];
    });
    
    dispatch_group_async(group, queue, ^{
        
        [self fakeRequestWithDelay:2 result:^(NSString *string, NSError *error) {
            
            NSLog(@"group 2...result = %@", string);
        }];
    });
    
    dispatch_group_async(group, queue, ^{
        [self fakeRequestWithDelay:1 result:^(NSString *string, NSError *error) {
            NSLog(@"group 3... result = %@", string);
        }];
    });
    
    // 3，所有queue执行完毕，回到主线程
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"all group end threadPriority = %f",threadPriority);
    });
}

// test 异步并发 GCD
- (void)testGCD_Group
{
    NSLog(@"testGCD_Group===============");
    // 1，创建异步队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 2，创建 一组 任务
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:3];
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"group 1... threadPriority = %f",threadPriority);
    });
    
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:2];
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"group 2... threadPriority = %f",threadPriority);
    });
    
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:1];
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"group 3... threadPriority = %f",threadPriority);
    });
    
    // 3，所有queue执行完毕，回到主线程
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        double threadPriority = [[NSThread currentThread] threadPriority];
        NSLog(@"all group end threadPriority = %f",threadPriority);
    });
}

// 串行任务
- (void)testGCD_Serial
{
    NSLog(@"testGCD_Serial===============");
    // 1，创建 队列
    dispatch_queue_t queue = dispatch_queue_create("gcd.devdiy", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"dispatch_async_1");
    });
    
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:0];
        NSLog(@"dispatch_async_2");
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"dispatch_barrier_async");
        [NSThread sleepForTimeInterval:2];
    });
    
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"dispatch_async_3");
    });
}

#pragma mark -

- (void)getJSONWithUrl:(NSString *)url result:(void (^)(id callback, NSError *error))result
{
    /**
     要使用常规的AFN网络访问
     
     1. AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
     
     所有的网络请求,均有manager发起
     
     2. 需要注意的是,默认提交请求的数据是二进制的,返回格式是JSON
     
     1> 如果提交数据是JSON的,需要将请求格式设置为AFJSONRequestSerializer
     2> 如果返回格式不是JSON的,
     
     3. 请求格式
     
     AFHTTPRequestSerializer            二进制格式
     AFJSONRequestSerializer            JSON
     AFPropertyListRequestSerializer    PList(是一种特殊的XML,解析起来相对容易)
     
     4. 返回格式
     
     AFHTTPResponseSerializer           二进制格式
     AFJSONResponseSerializer           JSON
     AFXMLParserResponseSerializer      XML,只能返回XMLParser,还需要自己通过代理方法解析
     AFXMLDocumentResponseSerializer (Mac OS X)
     AFPropertyListResponseSerializer   PList
     AFImageResponseSerializer          Image
     AFCompoundResponseSerializer       组合
     */
    
    //1.管理器
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    
    //2.设置response类型
    manager.responseSerializer = [AFPropertyListResponseSerializer serializer]; //是Response, 别写成request了. 修改为plist类型.
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/plain"]; //这个可以直接往框架里面修改. | 项目中搜索xuneng, 找到定位点.
    
    //3.请求
    [manager GET:url parameters:nil success: ^(AFHTTPRequestOperation *operation, id responseObject) {
        if (result) {
            result(responseObject, nil);
        }
    } failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
        if (result) {
            result(operation, error);
        }
    }];
}

- (void)postJSONWithUrl:(NSString *)url result:(void (^)(id callback, NSError *error))result
{
    //1.管理器
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    
    //2.设定类型. (这里要设置request-response的类型)
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //这个决定了下面responseObject返回的类型
    //    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    //  manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/plain"];
    
    //2.设置登录参数
    NSDictionary *dict = @{ @"username":@"xn", @"password":@"123" };
    
    //3.发送请求
    [manager POST:@"http://localhost/postjson.php" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
    } success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {
        //      NSLog(@"postjson--> %@", responseObject);  //这样显示JSON的话需要设置text/plain
        NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    } failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
        
    }];
}
@end
